package servlet;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import tournoi.modele.*;
import tournoi.stateless.TournoiFacade;

/**
 * Servlet permettant la gestion la partie admin du site. Cette servlet va
 * permettre de rediriger l'admin du site vers la bonne jsp, tout en envoyant
 * les informations nécessaires à l'affichage de celle ci. La servlet fait aussi
 * la relation entre la facade de nos objets et les jsp.
 * 
 * @author Florent Champigny, Kevin De Jesus Ferreira and Julien Mialon
 * 
 */
@WebServlet("/admin")
public class TournoiServletAdmin extends HttpServlet {

	private static final long serialVersionUID = -5041742716961413518L;
	/**
	 * Session du site
	 */
	HttpSession session;

	/**
	 * Facade stateless
	 */
	TournoiFacade tournoi;

	private static final String ADMIN_USERNAME = "admin";
	private static final String ADMIN_PASSWORD = "admin";

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public TournoiServletAdmin() {
		super();
	}

	/**
	 * Méthode permettant de lancer la page de connexion. L'admin y rentrera son
	 * identifiant et son mot de passe pour se connecter
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void lancerConnexionAdmin(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("/connexion_admin.jsp").forward(request,
				response);
	}

	/**
	 * Méthode permettant de lancer la page accueil de l'admin, sur celle ci on
	 * y retrouvera les actions possibles par l'administrateur
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void lancerAdmin(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		List<Match> matchs_en_cours = tournoi.getMatchByEtat(Match.EN_COURS);
		session.setAttribute("fixer", (matchs_en_cours.size() > 0));
		request.getRequestDispatcher("/admin.jsp").forward(request, response);
	}

	/**
	 * Méthode permettant de lancer la page pour l'ajout des arbitres. On y
	 * affichera la liste des arbitres déjà présent sur le site
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void lancerArbitres(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		List<Arbitre> arbitres = (List<Arbitre>) tournoi.getAllArbitres();
		session.setAttribute("arbitres", arbitres);
		request.getRequestDispatcher("/arbitres.jsp")
				.forward(request, response);
	}

	/**
	 * Permet de lancer la page pour l'affectation des arbitres à un match.
	 * L'arbitre ne pourra être affecter qu'à un seul match pour un tour
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void lancerAffecterArbitres(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		List<Arbitre> arbitres = tournoi.getAllArbitres();
		session.setAttribute("arbitres", arbitres);
		List<Tour> tours = tournoi.getAllTour();
		session.setAttribute("tours", tours);
		request.getRequestDispatcher("/affecter-arbitres.jsp").forward(request,
				response);
	}

	/**
	 * Méthode permettant de lancer la page pour la gestion des matchs. Sur
	 * cette page on pourra voir une liste des matchs par état (prévu, en cours
	 * ou finit)
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void lancerGererMatchs(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		List<Match> matchs_prevus = tournoi.getMatchByEtat(Match.PREVU);
		List<Match> matchs_en_cours = tournoi.getMatchByEtat(Match.EN_COURS);
		List<Match> matchs_finits = tournoi.getMatchByEtat(Match.FINIT);
		session.setAttribute("matchs_prevus", matchs_prevus);
		session.setAttribute("matchs_en_cours", matchs_en_cours);
		session.setAttribute("matchs_finits", matchs_finits);

		request.getRequestDispatcher("/gerer-matchs.jsp").forward(request,
				response);
	}

	/**
	 * Méthode permettant de lancer la page pour la gestion d'un match. En
	 * fonction de son état la page ne fera pas la même chose. On récupère pour
	 * cela le match grâce à la facade et son id. On l'ajoutera ensuite dans la
	 * session
	 * 
	 * @param id_match
	 *            - Id du match que l'on veut gérer
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void lancerGererMatch(int id_match, HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		Match match = tournoi.getMatchById(id_match);
		if (match != null) {
			session.setAttribute("match", match);
			request.getRequestDispatcher("/gerer-match.jsp").forward(request,
					response);
		} else
			lancerAdmin(request, response);
	}

	/**
	 * Méthode permettant de modifier un match. La modification se fait en
	 * fonction de l'action passée en paramètre. L'action peut être de débuter
	 * un match, d'ajouter un but à un match, finir un match, avancer le match,
	 * le passer en prolongation ou au tir au but. On pourra le modifier à
	 * l'aide de la facade
	 * 
	 * @param match_id
	 *            - Id du match que l'on veut modifier
	 * @param action_match
	 *            - Action que l'on veut effectuer sur le match
	 * @param request
	 */
	private void modifierMatch(int match_id, String action_match,
			HttpServletRequest request) {

		if (action_match.equals("debuter")) {
			String date = request.getParameter("date_debut");
			String time = request.getParameter("heure_debut");
			String dateTime = date + " " + time;

			tournoi.debuterMatch(match_id, dateTime);
		} else if (action_match.equals("ajouter-but")) {
			int minute = Integer.parseInt(request.getParameter("minute"));
			int typebut = Integer.parseInt(request.getParameter("typebut"));
			int joueur_id = Integer.parseInt(request.getParameter("joueur"));
			tournoi.ajouterBut(match_id, minute, typebut, joueur_id);
		} else if (action_match.equals("finir")) {
			tournoi.finirMatch(match_id);
			tournoi.fixerRencontres();
			Tournoi le_tournoi = tournoi.getTournoi();
			session.setAttribute("le_tournoi", le_tournoi);
		} else if (action_match.equals("prolongation")) {
			tournoi.matchToProlongation(match_id);
		} else if (action_match.equals("tiraubut")) {
			tournoi.matchToTirAuBut(match_id);
		} else if (action_match.equals("avancer-match")) {
			int minute = Integer.parseInt(request.getParameter("minute"));
			tournoi.avancerMatch(match_id, minute);
		}
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * Méthode permettant de rediriger l'admin en fonction d'une requête et
	 * d'une action.
	 * 
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String action = request.getParameter("action");

		session = request.getSession(true);
		tournoi = (TournoiFacade) session.getAttribute("tournoi");

		if (tournoi == null) {
			Context ctx;
			try {
				ctx = new InitialContext();
				tournoi = (TournoiFacade) ctx
						.lookup("java:global/TournoiWeb/TournoiFacade!tournoi.stateless.TournoiFacadeLocal");
			} catch (NamingException e) {
				e.printStackTrace();
			}
			session.setAttribute("tournoi", tournoi);
		}

		Boolean connecte = (Boolean) session.getAttribute("connecte");

		if (connecte == null || !connecte.booleanValue()) {
			if (action == null || !action.equals("login")) {
				lancerConnexionAdmin(request, response);
			} else {
				String username = request.getParameter("username");
				String password = request.getParameter("password");

				if (username != null && password != null
						&& username.equals(ADMIN_USERNAME)
						&& password.equals(ADMIN_PASSWORD)) {
					session.setAttribute("connecte", Boolean.TRUE);
					lancerAdmin(request, response);
				} else
					lancerConnexionAdmin(request, response);
			}
		} else {
			// connecte

			if (action == null) {
				lancerAdmin(request, response);
			} else if (action.equals("logout")) {
				session.setAttribute("connecte", Boolean.FALSE);
				lancerConnexionAdmin(request, response);
			} else if (action.equals("inscrire-arbitres")) {
				Set<Arbitre> arbitres = new HashSet<Arbitre>();

				String[] nomArbitre = request.getParameterValues("nom_arbitre");
				String[] prenomArbitre = request
						.getParameterValues("prenom_arbitre");

				if (nomArbitre != null && prenomArbitre != null) {
					for (int i = 0; i < nomArbitre.length; ++i) {
						Arbitre arbitre = new Arbitre();
						arbitre.setPrenom(prenomArbitre[i]);
						arbitre.setNom(nomArbitre[i]);
						arbitres.add(arbitre);
					}
					tournoi.addArbitres(arbitres);
					lancerArbitres(request, response);
				} else
					lancerArbitres(request, response);
			} else if (action.equals("fixer-rencontres")) {
				tournoi.fixerRencontres();
				Tournoi le_tournoi = tournoi.getTournoi();
				session.setAttribute("le_tournoi", le_tournoi);

				lancerAdmin(request, response);
			} else if (action.equals("affecter-arbitres")) {
				lancerAffecterArbitres(request, response);
			} else if (action.equals("affecter-arbitres-reponse")) {

				Map<String, String[]> parameters = request.getParameterMap();

				System.out.println(parameters);

				for (Map.Entry<String, String[]> parameter : parameters
						.entrySet()) {
					String key = parameter.getKey();
					String value = parameter.getValue()[0];

					System.out.println("key :" + key + " | value :" + value);

					if (!value.equals("-")) {

						System.out.println(key);
						System.out.println(value);

						String[] split = key.split("_");

						if (split.length == 3) {
							// Integer numero_tour = Integer.parseInt(split[1]);
							Integer id_match = Integer.parseInt(split[2]);

							Integer id_arbitre = Integer.parseInt(value);

							tournoi.affecterArbitreMatch(id_match, id_arbitre);
						}
					}
				}
				lancerAffecterArbitres(request, response);
			} else if (action.equals("gerer-matchs")) {
				lancerGererMatchs(request, response);
			} else if (action.equals("gerer-match")) {
				String id = request.getParameter("id");
				if (id != null && !id.equals("")) {
					int match_id = Integer.parseInt(id);

					String action_match = request.getParameter("action-match");
					if (action_match == null || action_match.equals("")) {
						lancerGererMatch(match_id, request, response);
					} else {
						modifierMatch(match_id, action_match, request);
						lancerGererMatch(match_id, request, response);
					}
				}
			}
		}
	}

}